﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Net;
using System.IO;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Threading;
using System.Linq.Expressions;

using Mr.HttpBodyWrapper;
using Mr.LinqToWeibo;
using Mr.LinqToWeibo.SearchCriteria;

namespace OAuth
{
	class Program
	{
		public static ServiceProvider provider = null;
		public static OAuthConsumer accessor = null;
		public static string mySinaSecret = "bee7898872f88095a151dd69dd4248ff";
		public static string appSecret = "a4f6a58e864e2fe1cd15d799d48c9f8e";

		public static void Main (string[] args)
		{
			
            IQueryableWeiboData<Weibo> data = new QueryableWeiboData<Weibo>();
            IQueryableWeiboData<Comment> comments = new QueryableWeiboData<Comment>();

            data.Provider.UseObjectFilter = false;

            string token = "da93398d447f247c98c96fe08f87f762";
            string secret = "f92807d4d991483ba3761641d6725a1c";

            data.SetAccessTokenAndSecret(
                token, // majia : "2b86af73326d980864d2732aad419de7",
                secret); // "bee7898872f88095a151dd69dd4248ff");

            comments.SetAccessTokenAndSecret(token, secret);

            data.SetWeiBoScope(Scope.FRIENDS_TIMELINE);
            comments.SetWeiBoScope(Scope.COMMENTS_FOR_ONE_WEIBO);

            var objs =
                data.Where(w => w.Feature == Feature.ALL && !w.BaseApp && w.Text.Contains("我")).PageIndex(0).PageSize(5);

            foreach (var obj in objs)
            {
                Console.WriteLine(obj.User.Name + ":" + obj.Text);
                var cmts = comments.Where(cmt => obj.Id == cmt.Weibo.Id).Take(5);
                foreach (var cmt in cmts)
                {
                    Console.Write("\t");
                    Console.WriteLine(cmt.User.Name + ":" + cmt.Text);
                }
            }
			
			//RequestBuzz();
			//RequestTSina();
		}

		public static void RequestBuzz ()
		{
			provider = new ServiceProvider (
                "https://www.google.com/accounts/OAuthGetRequestToken",
                "https://www.google.com/buzz/api/auth/OAuthAuthorizeToken", //"https://www.google.com/buzz/api/auth/OAuthAuthorizeToken",
                "https://www.google.com/accounts/OAuthGetAccessToken");

			accessor = new OAuthConsumer (
                "buzzzzble.appspot.com",
                "ZCP7ZE3BziaLM5y1jti2ZmGv",
                "http://localhost:8080/OAuthCallback");

			accessor.ServiceProvider = provider;

			string scope = "https://www.googleapis.com/auth/buzz";

			accessor.GetRequestToken (
                new OAuthQueryParameter ("scope", scope));

			Action<OAuthConsumer > handler = delegate(OAuthConsumer acsr)
			{
				StringBuilder urlBuilder = new StringBuilder ();
				urlBuilder
                        .AppendFormat ("{0}?", acsr.ServiceProvider.OAuthAuthorizeTokenUrl)
                        .AppendFormat ("{0}={1}&", OAuthUtility.OAuthTokenKey, acsr.Token)
                        .AppendFormat ("{0}={1}&", "scope", OAuthUtility.Instance.UrlEncode (scope))
                        .AppendFormat ("{0}={1}", "domain", "buzzzzble.appspot.com");

				// set return value, default null;
				NameValueCollection keyValues = null;
                #region FOR PC
				string callbackUrl = acsr.CallbackUrl;
				// create a web request listener
				using (HttpListener listerner = new HttpListener()) {
					listerner.AuthenticationSchemes = AuthenticationSchemes.Anonymous;
					// the prefixes should end with "/"
					if (!callbackUrl.EndsWith ("/")) {
						callbackUrl += "/";
					}
					listerner.Prefixes.Add (callbackUrl);
					listerner.Start ();

					// open the browser
					Process.Start (urlBuilder.ToString ());

					// start listening
					HttpListenerContext ctx = listerner.GetContext ();
					keyValues = ctx.Request.QueryString;
					if (keyValues != null
                            && !string.IsNullOrEmpty (keyValues [OAuthUtility.OAuthTokenKey])
                            && !string.IsNullOrEmpty (keyValues [OAuthUtility.OAuthVerifierKey])) {
						acsr.Token = keyValues [OAuthUtility.OAuthTokenKey];
						acsr.Verifier = keyValues [OAuthUtility.OAuthVerifierKey];
					} else {
						throw new ApplicationException ("Sorry!, the request is valid, meybe it returned the null value or the return values did not contains the token or verifier.");
					}
					// 200 successfully received the data
					ctx.Response.StatusCode = 200;
					string responseText = "<html><head><title>Please redirect to application</title></head><body><h1>Thanks</h1><p style=\"font-family:verdana;font-size:16px;\">Please back to application.</p></body></html>";

					using (StreamWriter writer = new StreamWriter(ctx.Response.OutputStream)) {
						writer.WriteLine (responseText);
					}
					listerner.Close ();
				}
                #endregion
			};

			// for pc, authorize the token.
			accessor.AuthorizeToken (handler);
			accessor.GetAccessToken ();
		}

		public static void RequestTSina ()
		{
			ServiceProvider provider = new ServiceProvider (
                "http://api.t.sina.com.cn/oauth/request_token",
                "http://api.t.sina.com.cn/oauth/authorize",
                "http://api.t.sina.com.cn/oauth/access_token");

			OAuthConsumer accessor = new OAuthConsumer (
                "297533609",
                appSecret);

			accessor.ServiceProvider = provider;

			// access token and secret
            //accessor.LoadAccessTokenAndSecret(
            //   "2b86af73326d980864d2732aad419de7", mySinaSecret
            //   );

			accessor.GetRequestToken ();
			// for pc, authorize the token.
			accessor.AuthorizeToken (
                delegate(OAuthConsumer acsr)
			{
				StringBuilder urlBuilder = new StringBuilder ();
				urlBuilder
                                .AppendFormat ("{0}?", acsr.ServiceProvider.OAuthAuthorizeTokenUrl)
                                .AppendFormat ("{0}={1}&", OAuthUtility.OAuthTokenKey, acsr.Token);
				Process.Start (urlBuilder.ToString ());
				Console.Write ("Enter the code:");
				acsr.Verifier = Console.ReadLine ();
					
			});
			accessor.GetAccessToken ();
            /*
          OAuthResponse response = accessor.InvokeAPI(
              new Uri("http://api.t.sina.com.cn/statuses/update.json"),
              OAuthHttpMethod.POST,
              new KeyValuesHttpBodyWrapper(
                      new OAuthQueryParameter("status", OAuthUtility.Instance.UrlEncode("LINQ To Weibo 代码又重构了。把Skip更换成PageIndex，Take更换成PageSize，更加有语意。"), false)
                  ));
          
          string fileUrl = "E:/appsources/desktop/1263022964821.jpg";
          string fileName = "Test.jpg";
          byte[] bytes = File.ReadAllBytes(fileUrl);

          OAuthResponse response = accessor.InvokeAPI(
              new Uri("http://api.t.sina.com.cn/statuses/upload.json"),
              OAuthHttpMethod.POST,
              new MultipartHttpBodyWrapper(
                      new OAuthQueryParameter("status", OAuthUtility.Instance.UrlEncode("依然是在测试。")),
                      new OAuthFileParameter("pic", fileName, bytes)
                  ));
          */
			//LogResponse(response);
		}

		private static void LogResponse (OAuthResponse response)
		{
			using (StreamReader reader = new StreamReader(response.GetResponseStream())) {
				Console.WriteLine (reader.ReadToEnd ());
			}
		}
	}
}